package gamagora.game.entity
{
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.Joints.b2Joint;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	import Box2D.Dynamics.b2Body;
	
	import gamagora.game.resources.OSImages;

	public class OSBridge extends OSEntity
	{
		// Pour le moment les ponts sont préfixés au niveau de la taille des planches/rondins
		// On peut déjà faire des trucs sympas avec ça.
		private static const PLANK_WIDTH:Number = 40.0;
		private static const PLANK_HEIGHT:Number = 10.0;
		private static const PLANK_RADIUS:Number = 10.0;
		
		private var _nbPlanks:uint;
		private var _circleBridge:Boolean;
		private var _crackAtMiddle:Boolean;
		private var _cracked:Boolean;
		private var _anchor:b2Vec2;
		private var _jd:b2RevoluteJointDef;
		private var _plankWidth:Number;
		private var _plankHeight:Number;
		private var _middleJoint:b2Joint;
		private var _xMid:Number;
		
		public function OSBridge(X:Number=0, Y:Number=0, nbPlanks:uint = 10, plankHeight:uint = 10, circleBridge:Boolean = false, crackAtMiddle:Boolean = false)
		{	
			super(BRIDGE, X, Y);
			_nbPlanks = nbPlanks;
			_circleBridge = circleBridge;
			_crackAtMiddle = crackAtMiddle;
			_plankHeight = plankHeight;
			_hide = true;
			_cracked = false;
		}
		
		public override function addToWorld():void
		{
			_inWorld = true;

			var ground:b2Body = _world.physicWorld.GetGroundBody();
			var prevBody:b2Body = ground;
			
			var midEnt:uint = _nbEntities * 0.5;
			for(var i:uint=0;i<_nbEntities;i++)
			{
				var plank:OSPhysicEntity = _entities[i] as OSPhysicEntity;
				if(!plank.inWorld)
				{
					plank.resetEntity();
					addEntityToWorld(plank);
					
					_anchor.Set((x + _plankWidth * i) / OSPhysicEntity.RATIO, y / OSPhysicEntity.RATIO);
					_jd.Initialize(prevBody, plank.body, _anchor);
					
					var j:b2Joint = _world.physicWorld.CreateJoint(_jd);
					if(i == midEnt)
					{
						_middleJoint = j;
					}
					
					prevBody = plank.body;
				}
			}
			
			_anchor.Set((x + _plankWidth * _nbEntities) / OSPhysicEntity.RATIO, y / OSPhysicEntity.RATIO);
			_jd.Initialize(prevBody, ground, _anchor);
			_world.physicWorld.CreateJoint(_jd);
		}
		
		public override function setStartX(decalX:Number):void
		{
			x += decalX;
			_startX += decalX;
			
			_anchor = new b2Vec2();
			_jd = new b2RevoluteJointDef();
			_jd.lowerAngle = -15 / (180 / Math.PI);
			_jd.upperAngle = 15 / (180 / Math.PI);
			_jd.enableLimit = true;
			
			_plankWidth = _circleBridge ? PLANK_RADIUS * 2 : PLANK_WIDTH;
			
			for (var i:uint = 0; i < _nbPlanks; i++)
			{
				var plank:OSPhysicEntity;
				if(_circleBridge)
				{
					plank = new OSCircle(BRIDGE, (x + PLANK_RADIUS + (PLANK_RADIUS * 2) * i), y, PLANK_RADIUS, OSImages.BALL);
				}
				else 
				{
					plank = new OSBox(BRIDGE, (x + (PLANK_WIDTH / 2) + PLANK_WIDTH * i), y, PLANK_WIDTH, _plankHeight);
					plank.makeGraphic(PLANK_WIDTH + 2, _plankHeight, 0xff000000);
				}
				
				plank.bodyDef.position.Set((x + (_plankWidth / 2) + _plankWidth * i) / OSPhysicEntity.RATIO, y / OSPhysicEntity.RATIO);
				plank.bodyDef.type = b2Body.b2_dynamicBody;
				plank.fixDef.friction = 0;
				plank.fixDef.density = 0.2;
				
				add(plank);
			}
			
			_xMid = x + ((_nbPlanks * 0.5) * _plankWidth);
		}
		
		public override function update():void
		{
			super.update();
			
			if(!_cracked && _crackAtMiddle && _world.getPlayerX() >= _xMid)
			{
				if(_middleJoint != null)
				{
					_world.physicWorld.DestroyJoint(_middleJoint);
					_cracked = true;
				}
			}
		}
	}
}
